/**
 * 一个解析url的扩展，默认解析location.href，否则解析传入的url
 */
(function ($) {
    var getSearchParams = function (searchText) {
        if (searchText.indexOf("?") !== 0) {
            return {};
        }
        searchText = searchText.substring(1);
        if (searchText === "") {
            return {};
        }
        var searchTextArray = [];
        searchTextArray = searchText.split("&");
        var searchParams = {};
        for (var i = 0; i < searchTextArray.length; i++) {
            var kv = searchTextArray[i].split("=");
            var k = kv[0];
            var v = kv[1];
            searchParams[k] = v;
        }
        return searchParams;
    };
    $.extend({
        /**
         * 实现像后端一样，通过request对象获取get请求传递的参数
         */
        urlAnalysis: function (url) {
            if (!url) {
                url = location.href;
            }
            //处理 url 参数中带有 % 的情况，需要转换为% 的转义符 %25
            url=url.replace(/%/g,"%25");
            url=decodeURIComponent(url);
            var questionMarkCount = 0;
            var hashMarkCount = 0;
            for (var i = 0; i < url.length; i++) {
                var c = url[i];
                if (c === "?") {
                    questionMarkCount++;
                }
                if (c === "#") {
                    hashMarkCount++;
                }
            }

            if (questionMarkCount > 1 || hashMarkCount > 1) {
                throw new Error("url 中包含的 ? 或者 # 最多只能有一个");
            }

            if (url.indexOf("http") !== 0) {
                throw new Error(
                    "此函数仅能解析带有(http/https)协议的url，如: http://www.example.com"
                );
            }

            var href = url;
            var urlInstance = new URL(url);

            url = url.toLowerCase();

            //协议 http https
            var protocol = "";
            //主机名 域名 ip
            var host = "";
            //端口 80 443
            var port = "";
            //协议端口默认值
            var portDefault = "";
            //访问路径
            var pathname = "";
            //查询字符串
            var search = "";
            //hash值
            var hash = "";

            /**
             * 匹配协议
             * 匹配规则：
             * 1.// 分隔，前一部分就是协议
             */
            var sep = "//";
            var index = url.indexOf(sep);
            protocol = url.substring(0, index);
            url = url.substring(index + sep.length);

            //指定默认端口
            if (protocol === "http:") {
                portDefault = "80";
            }

            if (protocol === "https:") {
                portDefault = "443";
            }

            /**
             * 匹配主机名，可能是域名，或者ip地址和端口
             * 匹配规则：
             * 1. 先通过第一个 / 把主机和端口截取出来
             * 2. 判断截取的字符串里面是否包含 :，如果有则端口不是默认端口
             */
            sep = "/";
            index = url.indexOf(sep);
            //如 http://www.example.com?a=1,没有访问路径，只有域名和参数的情况下
            if (index === -1) {
                sep = "?";
                index = url.indexOf(sep);
            }
            var hostAndPort = url.substring(0, index);
            if (hostAndPort.indexOf(":") > -1) {
                var hostAndPortArr = hostAndPort.split(":");
                host = hostAndPortArr[0];
                port = hostAndPortArr[1];
            } else {
                host = hostAndPort;
            }

            url = url.substring(index);
            /**
             * 匹配路径名称，查询字符串，hash值
             * 匹配规则：
             * 1. 匹配 hash 值，以第一个 # 符号为开始，后面部分都是hash的内容，hash值包含#本身
             * 2. 匹配 search 段，以第一个 ? 符号为开始，以 # 结束或者整行，search 段包含?本身
             * 3. 上面的匹配完成后剩下的就是 pathname 段
             */
            //匹配 hash 段
            sep = "#";
            index = url.indexOf(sep);
            if (index > -1) {
                hash = url.substring(index);
                url = url.substring(0, index);
            }
            //匹配 search 段
            sep = "?";
            index = url.indexOf(sep);
            if (index > -1) {
                search = url.substring(index);
                url = url.substring(0, index);
            }

            pathname = url;

            var hostname = host + (port === "" ? "" : ":" + port);
            var origin = protocol + "//" + hostname;
            var searchParams = getSearchParams(search);
            var pathnameArray = [];
            var pArr = pathname.split("/");
            for (var i = 0; i < pArr.length; i++) {
                var path = pArr[i];
                if (path === "") {
                    continue;
                }
                pathnameArray.push(path);
            }

            if (pathname === "") {
                pathname = "/";
                pathnameArray = [];
            }

            var obj = {
                href: href,
                urlInstance: urlInstance,
                protocol: protocol,
                host: host,
                port: port,
                portDefault: portDefault,
                pathname: pathname,
                pathnameArray: pathnameArray,
                search: search,
                searchParams: searchParams,
                hash: hash,
                hostname: hostname,
                origin: origin,
                /**
                 * 根据查询key获取key对应的值
                 * @param {string} key 查询key（不区分大小写）
                 */
                getSearchValue: function (key) {
                    var searchParams = this.searchParams;
                    key = key.toLocaleLowerCase();
                    var val = "";
                    for (var k in searchParams) {
                        k = k.toLocaleLowerCase();
                        if (searchParams.hasOwnProperty(k) && k === key) {
                            val = searchParams[k];
                            break;
                        }
                    }
                    return val;
                },
            };

            return obj;
        },
    });
})(jQuery);
